/* 在该程序中，父进程在分支一个子进程执行ls命令前阻塞了所有的信号，进程在fork和exec后继承了信号掩码，因此，ls命令是在信号被阻塞时执行的
 * 该程序中由fork重建的子进程在oldmask中保存着一份原始信号掩码的拷贝
 * exec命令会重写所有的程序变量，因此，一旦执行了exec，被执行的进程就无法恢复原始掩码了
 * 父进程恢复原始掩码，然后等待子进程
 * */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <signal.h>

int main(int argc, char *argv[]) {
    sigset_t blockmask, oldmask;
    pid_t childpid;

    // 阻塞所有的子进程
    if (sigfillset(&blockmask) == -1 || sigprocmask(SIG_SETMASK, &blockmask, &oldmask)) {
        perror("Failed to block the signals");
        return -1;
    }

    if ((childpid = fork()) == -1) {
        perror("Failed to fork child");
        return -1;
    }

    // 子进程函数
    if (childpid == 0) {
        // 在子进程中执行exec命令
        execl("/bin/ls", "ls", "-l", argv[1], NULL);
        perror("Child failed to exec");
        return 1;
    } else {
        // 父进程代码,恢复信号
        if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
            perror("Parent failed to restore signal mask");
            return 1;
        }
    }

    return 0;
}